package com.ruoyi.project.app.intercepter;

import com.github.pagehelper.PageHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.page.PageDomain;
import com.ruoyi.framework.web.page.TableSupport;
import com.ruoyi.project.app.util.XException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Set;

@Component
@Aspect
@SuppressWarnings("ALL")
public class FilterInterceptor {
    @Autowired
    private Validator validator;

    @Around(value = "@annotation(FilterAnnotation)")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;

        // 获取方法识别标志
        MethodSignature sign = (MethodSignature) joinPoint.getSignature();
        // 获取方法
        Method method = sign.getMethod();
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        // 获取注解
        FilterAnnotation filter = method.getDeclaredAnnotation(FilterAnnotation.class);
        if (filter.validator()) validatorEntity(args);
        if (filter.page()) startPage();
        return joinPoint.proceed(args);
    }

    /**
     * 验证参数对象
     *
     * @param objects 验证对象集合
     * @return 验证结果
     */
    private void validatorEntity(Object[] objects) {
        for (Object object : objects) {
            if (object != null) {
                Class<?> clazz = object.getClass();
                // 校验实体类
                if (clazz.isAnnotationPresent(FilterModel.class)) {
                    Set validate = validator.validate(object);
                    // 验证结果
                    if (!validate.isEmpty()) {
                        Iterator iterator = validate.iterator();
                        if (iterator.hasNext()) {
                            Object next = iterator.next();
                            if (next != null) {
                                ConstraintViolation violation = (ConstraintViolation) next;
                                throw new XException(violation.getMessage());
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 设置请求分页数据
     */
    protected void startPage() {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
            String orderBy = pageDomain.getOrderBy();
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }
}
